﻿@page "/Account/Manage/TwoFactorAuthentication"

@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Identity
@using MyApp.Data
@using MyApp.Identity

@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject UserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager

<PageTitle>Two-factor authentication (2FA)</PageTitle>

<Heading3>Two-factor authentication (2FA)</Heading3>

<div class="max-w-xl">
    <StatusMessage class="mb-3" />

    @if (_consentFeature?.CanTrack ?? true)
    {
        if (_is2faEnabled)
        {
            if (_recoveryCodesLeft == 0)
            {
                <Alert Type="AlertType.Error">
                    <strong>You have no recovery codes left.</strong>
                    <p>You must <HyperLink href="/Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</HyperLink> before you can log in with a recovery code.</p>
                </Alert>
            }
            else if (_recoveryCodesLeft == 1)
            {
                <Alert Type="AlertType.Error">
                    <strong>You have 1 recovery code left.</strong>
                    <p>You can <HyperLink href="/Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</HyperLink>.</p>
                </Alert>
            }
            else if (_recoveryCodesLeft <= 3)
            {
                <Alert Type="AlertType.Error">
                    <strong>You have @_recoveryCodesLeft recovery codes left.</strong>
                    <p>You should <HyperLink href="/Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</HyperLink>.</p>
                </Alert>
            }

            if (_isMachineRemembered)
            {
                <form class="inline-block" @formname="forget-browser" @onsubmit="OnSubmitForgetBrowserAsync" method="post">
                    <PrimaryButton type="submit">Forget this browser</PrimaryButton>
                </form>
            }

            <PrimaryButton href="/Account/Manage/Disable2fa">Disable 2FA</PrimaryButton>
            <PrimaryButton href="/Account/Manage/GenerateRecoveryCodes">Reset recovery codes</PrimaryButton>
        }

        <div class="mt-4">
            <Heading4 class="mb-4">Authenticator app</Heading4>
            @if (!_hasAuthenticator)
            {
                <PrimaryButton id="enable-authenticator" href="/Account/Manage/EnableAuthenticator">Add authenticator app</PrimaryButton>
            }
            else
            {
                <PrimaryButton id="enable-authenticator" href="/Account/Manage/EnableAuthenticator">Set up authenticator app</PrimaryButton>
                <PrimaryButton id="reset-authenticator" href="/Account/Manage/ResetAuthenticator">Reset authenticator app</PrimaryButton>
            }
        </div>
    }
    else
    {
        <Alert Type="AlertType.Error">
            <strong>Privacy and cookie policy have not been accepted.</strong>
            <p>You must accept the policy before you can enable two factor authentication.</p>
        </Alert>
    }

</div>

@code {
    private ApplicationUser? _user;
    private ITrackingConsentFeature? _consentFeature;
    private bool _hasAuthenticator;
    private int _recoveryCodesLeft;
    private bool _is2faEnabled;
    private bool _isMachineRemembered;

    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        _user = await UserAccessor.GetRequiredUserAsync();
        _consentFeature = HttpContext.Features.Get<ITrackingConsentFeature>();
        _hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(_user) is not null;
        _is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(_user);
        _isMachineRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(_user);
        _recoveryCodesLeft = await UserManager.CountRecoveryCodesAsync(_user);
    }

    private async Task OnSubmitForgetBrowserAsync()
    {
        await SignInManager.ForgetTwoFactorClientAsync();

        RedirectManager.RedirectToCurrentPageWithStatus(
            "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.");
    }
}
